﻿/*
 * KLF Headless Browser
 * Written by Kris Oye <kristianoye@gmail.com>
 * Copyright (C) 2011-2012.  All rights reserved.
 */
namespace KLF.Lib.Browser.DOM.CSS
{
    #region Using Statements

    using System;
    using System.Linq;
    using System.Text;
    using KLF.Lib.Browser.DOM.Style;
    using System.Collections.Generic;

    #endregion

    /// <summary>
    /// The CSSStyleSheet interface is a concrete interface used to represent 
    /// a CSS style sheet i.e., a style sheet whose content type is "text/css".
    /// </summary>
    public class CSSStyleSheet : StyleSheet
    {
        #region Constructors

        public CSSStyleSheet()
        {
            Rules = new List<CSSRule>();
        }

        #endregion

        #region Attributes

        internal List<CSSRule> Rules { get; set; }

        #endregion

        #region DOM Level 2 CSS Compliance

        /// <summary>
        /// Adds a new rule to the stylesheet.
        /// </summary>
        /// <param name="rule"></param>
        internal void AddRule(CSSRule rule)
        {
            if (rule != null)
            {
                rule.parentStyleSheet = this;
                if (!Rules.Contains(rule))
                    Rules.Add(rule);
            }
        }

        /// <summary>
        /// The list of all CSS rules contained within the style sheet. This 
        /// includes both rule sets and at-rules.
        /// </summary>
        public CSSRuleList cssRules
        {
            get
            {
                return new CSSRuleList(Rules);
            }
        }

        /// <summary>
        /// Used to delete a rule from the style sheet. 
        /// </summary>
        /// <param name="index">The index within the style sheet's rule list 
        /// of the rule to remove.</param>
        public void deleteRule(int index)
        {
            if (index < 0 || index > cssRules.length)
                throw new DOMException(DOMException.INDEX_SIZE_ERR);
            else
                cssRules.RemoveAt(index);
        }

        /// <summary>
        /// Used to insert a new rule into the style sheet. The new rule now 
        /// becomes part of the cascade. 
        /// </summary>
        /// 
        /// <param name="rule">The parsable text representing the rule. For 
        /// rule sets this contains both the selector and the style 
        /// declaration. For at-rules, this specifies both the at-identifier
        /// and the rule content.</param>
        /// 
        /// <param name="index">The index within the style sheet's rule list
        /// of the rule before which to insert the specified rule. If the 
        /// specified index is equal to the length of the style sheet's rule
        /// collection, the rule will be added to the end of the style sheet.</param>
        /// 
        /// <returns>The index within the style sheet's rule collection 
        /// of the newly inserted rule.</returns>
        public int insertRule(string rule, int index)
        {
            if (index < 0 || index > cssRules.length)
                throw new DOMException(DOMException.INDEX_SIZE_ERR);
            else if (index == cssRules.length)
                cssRules.Add(new CSSRule());
            else
                cssRules.Insert(index, new CSSRule());
            return index;
        }

        /// <summary>
        /// If this style sheet comes from an @import rule, the ownerRule 
        /// attribute will contain the CSSImportRule. In that case, the 
        /// ownerNode attribute in the StyleSheet interface will be null. If 
        /// the style sheet comes from an element or a processing instruction,
        /// the ownerRule attribute will be null and the ownerNode attribute
        /// will contain the Node.
        /// </summary>
        public CSSRule ownerRule
        {
            get;
            internal set;
        }

        #endregion
    }
}
